package com.anjingsi.tools.list;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

import static com.anjingsi.tools.utils.PrintArray.printArray;

/**
 * @program: 稀疏数组
 * @description
 * @author: 安静思
 * @create: 2019-12-10 11:45
 **/
@Slf4j
public class SparseArray {

    private static String fileName = "D:\\my\\robot1\\zssj\\plat-user\\OutputSpecifiedSequence.txt";

    public static void main(String[] args) throws IOException {
        int[][] array = createTwoDimensionalArray(11,11);
        init(array);
        printArray(array);
        int[][] sparseArray = twoDimensionalArrayToSparseArray(array, 0);
        arrayToWriteFile(new File(fileName),sparseArray);

        int[][] ints = readFileSparseArray(new File(fileName));
        printArray(ints);
        printArray(sparseArrayToTwoDimensionalArray(ints));
    }

    public static int[][] readFileSparseArray(File file) throws IOException {
        if(!file.exists()){
            throw new FileNotFoundException("文件不存在");
        }
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        String line = null;
        int[][] sparseArray = null;
        //是否读取的为第一行
        boolean flag = false;
        int row = 0;
        while (( line = bufferedReader.readLine()) != null){
            String[] split = line.split("\t");
            if(!flag){
                flag = true;
                sparseArray = new int[Integer.valueOf(split[2])+1][3];
            }
            sparseArray[row][0] = Integer.valueOf(split[0]);
            sparseArray[row][1] = Integer.valueOf(split[1]);
            sparseArray[row][2] = Integer.valueOf(split[2]);
            row++;
        }
        return sparseArray;
    }
    /**
     * 将稀疏数组写入文件中
     * @param file
     * @param array
     * @throws IOException
     */
    public static void arrayToWriteFile(File file,int[][] array) throws IOException {
        if(isEmpty(array)){
            return;
        }
        if(!file.exists()){
            file.createNewFile();
        }
        FileWriter fileWriter = new FileWriter(file);
        for (int i = 0; i < array.length ; i++) {
            for (int j = 0; j < array[i].length ; j++) {
                fileWriter.write(array[i][j]+"\t");
            }
            fileWriter.write("\n");
        }
        fileWriter.flush();
        fileWriter.close();
    }

    /**
     * 创建二维数组
     * @return
     */
    public static int[][] createTwoDimensionalArray(int row,int column){
        return new int[row][column];
    }

    /**
     * 初始化数据
     * @param array
     */
    public static void init(int[][] array){
        array[1][2] = 1;
        array[2][4] = 2;
        array[4][6] = 1;
        array[5][9] = 2;
    }

    /**
     * 二维数组转稀疏数组
     * @param array
     * @param invalidValue
     * @return
     */
    public static int[][] twoDimensionalArrayToSparseArray(int[][] array,int invalidValue){
        if(isEmpty(array)){
            return null;
        }
        //保存数组内有效值的个数
        int sum = getTwoDimensionalArrayEffectiveValueNumber(array,invalidValue) ;
        int row = array.length;
        int column = array[0].length;
        int[][] sparseArray = new int[sum+1][3];
        sparseArray[0][0] = row;
        sparseArray[0][1] = column;
        sparseArray[0][2] = sum;
        if(sum == 0){
            return sparseArray;
        }
        int temp = 1;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                if(array[i][j] != 0){
                    sparseArray[temp][0] = i;
                    sparseArray[temp][1] = j;
                    sparseArray[temp][2] = array[i][j];
                    temp ++;
                }
            }
        }
        return sparseArray;
    }

    /**
     * 稀疏数组转二维数组
     * @param array
     * @return
     */
    public static int[][] sparseArrayToTwoDimensionalArray(int[][] array){
        if(isEmpty(array)) {
            return null;
        }
        int[][] twoDimensionalArray = new int[array[0][0]][array[0][1]];
        if(array[0][2] <= 0){
            return twoDimensionalArray;
        }
        for (int i = 0; i < array[0][2]; i++) {
            int[] current = array[i+1];
            twoDimensionalArray[current[0]][current[1]] = current[2];
        }
        return twoDimensionalArray;
    }

    /**
     * 获取二维数组的有效值
     * @param array
     * @param invalidValue
     * @return
     */
    public static int getTwoDimensionalArrayEffectiveValueNumber(int[][] array,int invalidValue){
        int sum = 0;
        //计算数组内的有效值的个数
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                if(array[i][j] != invalidValue){
                    sum ++;
                }
            }
        }
        return sum;
    }

    public static boolean isEmpty(int[][] array){
        return array == null || array.length == 0;
    }
}

